package com.shbaiche.bifenba.net;

import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.internal.ObjectConstructor;
import com.shbaiche.bifenba.common.Constants;
import com.shbaiche.bifenba.model.base.MessagePackage;
import com.shbaiche.bifenba.model.base.TransMessage;
import com.shbaiche.bifenba.model.base.TransType;
import com.shbaiche.bifenba.model.data.CompeteGroupMessage;
import com.shbaiche.bifenba.model.data.CompeteMatchesMessage;
import com.shbaiche.bifenba.model.data.ShooterMessage;
import com.shbaiche.bifenba.model.data.StandingMessage;
import com.shbaiche.bifenba.model.data.TeamDynamicMessage;
import com.shbaiche.bifenba.model.data.TeamFollowMessage;
import com.shbaiche.bifenba.model.data.TeamInfoMessage;
import com.shbaiche.bifenba.model.data.TeamRankMessage;
import com.shbaiche.bifenba.model.match.EaseChatMessage;
import com.shbaiche.bifenba.model.match.EasePhotoMessage;
import com.shbaiche.bifenba.model.match.EaseRegisterMessage;
import com.shbaiche.bifenba.model.match.MatchesAnalyseMessage;
import com.shbaiche.bifenba.model.match.MatchesGuessMessage;
import com.shbaiche.bifenba.model.match.MatchesInfoMessage;
import com.shbaiche.bifenba.model.match.MatchesLineupMessage;
import com.shbaiche.bifenba.model.match.MatchesListMessage;
import com.shbaiche.bifenba.model.match.MatchesOutsMessage;
import com.shbaiche.bifenba.model.match.OddsInfoMessage;
import com.shbaiche.bifenba.model.user.AboutMessage;
import com.shbaiche.bifenba.model.user.FavariteMessage;
import com.shbaiche.bifenba.model.user.FollowCancelMessage;
import com.shbaiche.bifenba.model.user.FollowListMessage;
import com.shbaiche.bifenba.model.user.FollowUpdateMessage;
import com.shbaiche.bifenba.model.user.LoginMessage;
import com.shbaiche.bifenba.model.user.MyDiscussMessage;
import com.shbaiche.bifenba.model.user.MyFollowMessage;
import com.shbaiche.bifenba.model.user.ShareMessage;
import com.shbaiche.bifenba.model.user.UserCommentMessage;
import com.shbaiche.bifenba.model.user.UserInfoMessage;
import com.shbaiche.bifenba.model.video.ArticleCollectMessage;
import com.shbaiche.bifenba.model.video.ArticleDetailMessage;
import com.shbaiche.bifenba.model.video.ArticleGroupListMessage;
import com.shbaiche.bifenba.model.video.ArticleListMessage;
import com.shbaiche.bifenba.model.video.ArticleShareMessage;
import com.shbaiche.bifenba.model.video.AuthorMessage;
import com.shbaiche.bifenba.model.video.CustomMessage;
import com.shbaiche.bifenba.model.video.DiscussAddMessage;
import com.shbaiche.bifenba.model.video.DiscussFollowMessage;
import com.shbaiche.bifenba.model.video.DiscussListMessage;
import com.shbaiche.bifenba.model.video.HotMatchesMessage;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.Callback;

import org.json.JSONArray;

import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.UUID;

import com.shbaiche.bifenba.model.GankResults;

import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.Response;


public class NetApi {

    public static final GsonBuilder gsonBuilder = createGson();

    public static void getGankData(String type, int pageSize, int pageNum, JsonCallback<GankResults> callback) {
        String url = UrlKit.getUrl(UrlKit.ACTION_DATA_RESULT);
        url = url.replace("{type}", type)
                .replace("{number}", "" + pageSize)
                .replace("{page}", "" + pageNum);

        invokeGet(url, null, callback);
    }

    //====================== 我的模块 ============================//

    public static void login(LoginMessage message, Callback callback) {
        doPost(message, TransType.Login, callback);
    }

    public static void sendSms(LoginMessage message, Callback callback) {
        doPost(message, TransType.SendSms, callback);
    }

    public static void UserInfo(UserInfoMessage message, Callback callback) {
        doPost(message, TransType.UserInfo, callback);
    }

    public static void About(AboutMessage message, Callback callback) {
        doPost(message, TransType.About, callback);
    }

    // 反馈
    public static void UserComment(UserCommentMessage message, Callback callback) {
        doPost(message, TransType.UserComment, callback);
    }

    // 我的收藏
    public static void MyFavorite(FavariteMessage message, Callback callback) {
        doPost(message, TransType.MyFavorite, callback);
    }

    public static void UploadPhoto(LoginMessage message, Callback callback) {
        doPost(message, TransType.UploadPhoto, callback);
    }

    public static void UpdateNickName(LoginMessage message, Callback callback) {
        doPost(message, TransType.UpdateNickName, callback);
    }

    public static void UpdateSex(LoginMessage message, Callback callback) {
        doPost(message, TransType.UpdateSex, callback);
    }

    //分享
    public static void Share(ShareMessage message, Callback callback) {
        doPost(message, TransType.Share, callback);
    }

    //分享
    public static void ArticleShare(ArticleShareMessage message, Callback callback) {
        doPost(message, TransType.ArticleShare, callback);
    }

    //我的评论
    public static void MyDiscuss(MyDiscussMessage message, Callback callback) {
        doPost(message, TransType.MyDiscuss, callback);
    }

    //我的评论
    public static void MyFollow(MyFollowMessage message, Callback callback) {
        doPost(message, TransType.MyFollow, callback);
    }

    //可关注列表(球队)
    public static void FollowList(FollowListMessage message, Callback callback) {
        doPost(message, TransType.FollowList, callback);
    }

    // 修改关注(球队)
    public static void FollowUpdate(FollowUpdateMessage message, Callback callback) {
        doPost(message, TransType.FollowUpdate, callback);
    }
    // 取消关注(球队)
    public static void FollowCancel(FollowCancelMessage message, Callback callback) {
        doPost(message, TransType.FollowCancel, callback);
    }


    //====================== 视频资讯模块 ============================//

    public static void videoTitle(ArticleGroupListMessage message, Callback callback) {
        doPost(message, TransType.ArticleGroupList, callback);
    }

    public static void videoList(ArticleListMessage message, Callback callback) {
        doPost(message, TransType.ArticleList, callback);
    }

    // 资讯或视频详情
    public static void videoListDetail(ArticleDetailMessage message, Callback callback) {
        doPost(message, TransType.ArticleDetail, callback);
    }

    // 资讯或视频收藏
    public static void ArticleCollect(ArticleCollectMessage message, Callback callback) {
        doPost(message, TransType.ArticleCollect, callback);
    }

    // 发表评论
    public static void ArticleDiscussAdd(DiscussAddMessage message, Callback callback) {
        doPost(message, TransType.ArticleDiscussAdd, callback);
    }

    // 评论列表
    public static void ArticleDiscussList(DiscussListMessage message, Callback callback) {
        doPost(message, TransType.ArticleDiscussList, callback);
    }

    // 点赞
    public static void ArticleDiscussFollow(DiscussFollowMessage message, Callback callback) {
        doPost(message, TransType.ArticleDiscussFollow, callback);
    }

    // 点赞
    public static void AuthorDetail(AuthorMessage message, Callback callback) {
        doPost(message, TransType.AuthorDetail, callback);
    }

    // 热门赛事
    public static void HotMatches(HotMatchesMessage message, Callback callback) {
        doPost(message, TransType.HotMatches, callback);
    }
    // 定制
    public static void MyCustom(CustomMessage message, Callback callback) {
        doPost(message, TransType.MyCustom, callback);
    }



    //==================================================//


    //====================== 数据模块 ============================//
    //获取分类
    public static void dataGroup(CompeteGroupMessage message, Callback callback) {
        doPost(message, TransType.CompeteGroup, callback);
    }

    //积分
    public static void dataStanding(StandingMessage message, Callback callback) {
        doPost(message, TransType.Standing, callback);
    }

    // 数据--球员榜
    public static void dataPlayerRank(ShooterMessage message, Callback callback){
        doPost(message,TransType.PlayerRank,callback);
    }

    // 数据--球队榜
    public static void dataTeamRank(TeamRankMessage message, Callback callback){
        doPost(message,TransType.TeamRank,callback);
    }

    // 数据--赛程
    public static void dataCompeteMatches(CompeteMatchesMessage message, Callback callback){
        doPost(message,TransType.CompeteMatches,callback);
    }

    // 球队详情
    public static void teamInfo(TeamInfoMessage message, Callback callback){
        doPost(message,TransType.TeamInfo,callback);
    }

    // 球队动态
    public static void teamDynamic(TeamDynamicMessage message, Callback callback){
        doPost(message,TransType.TeamDynamic,callback);
    }

    // 关注球队/赛事
    public static void teamFollow(TeamFollowMessage message, Callback callback){
        doPost(message,TransType.TeamFollow,callback);
    }

    // 单个取消关注
    public static void followCancel(FollowCancelMessage message, Callback callback){
        doPost(message,TransType.FollowCancel,callback);
    }



    //==================================================//

    //====================== 比分模块 ============================//
    //比赛列表
    public static void matchesList(MatchesListMessage message, Callback callback) {
        doPost(message, TransType.MatchesList, callback);
    }

    // 比赛阵容
    public static void matchesLineup(MatchesLineupMessage message, Callback callback) {
        doPost(message, TransType.MatchesLineup, callback);
    }


    // 比赛详情
    public static void matchesInfo(MatchesInfoMessage message, Callback callback) {
        doPost(message, TransType.MatchesInfo, callback);
    }

    // 比赛赛况
    public static void matchesOuts(MatchesOutsMessage message, Callback callback) {
        doPost(message, TransType.MatchesOuts, callback);
    }

    // 比赛分析
    public static void matchesAnalyse(MatchesAnalyseMessage message, Callback callback) {
        doPost(message, TransType.MatchesAnalyse, callback);
    }

    // 比赛竞猜支持
    public static void matchesGuess(MatchesGuessMessage message, Callback callback) {
        doPost(message, TransType.MatchesGuess, callback);
    }

    // 比赛赔率
    public static void matchesOddsInfo(OddsInfoMessage message, Callback callback) {
        doPost(message, TransType.OddsInfo, callback);
    }


    //==================================================//

    //====================== 比分模块 ============================//

    // 环信聊天室
    public static void easeChat(EaseChatMessage message, Callback callback) {
        doPost(message, TransType.EaseChat, callback);
    }

    // 环信用户注册
    public static void easeRegister(EaseRegisterMessage message, Callback callback) {
        doPost(message, TransType.EaseRegister, callback);
    }

    // 聊天室用户昵称、头像获取
    public static void easePhoto(EasePhotoMessage message, Callback callback) {
        doPost(message, TransType.EasePhoto, callback);
    }



    //==================================================//


    public static void doPost(TransMessage parameter, final TransType transType, final Callback callback) {
        String url = Constants.SERVER_BASE + Constants.ACCESS_SERVICE_PORT_URL;
        final Gson create = gsonBuilder.create();

        String json = create.toJson(parameter);

        Log.e("t", "=" + json);

        String date = formatDate("yyyyMMddHHmmss", new Date());
        String clientId = "201800";
        String clientKey = "1928baccb5f65a0adafff23ef5942b51";

        String messageId = UUID.randomUUID().toString();
        String md5Hex = DigestAuthUtils.md5Hex(clientId + "#" + clientKey + "#" + messageId + "#"
                + date + "#"
                + json);

//        String md5Hex = DigestAuthUtils.md5Hex(messageId + "#" + clientKey + "#" + clientId + "#" + transType + "#"
//                + json + "#"
//                + date + "#"
//                + parameter.getVersion());


        MessagePackage messagePackage = null;
        try {
            messagePackage = new MessagePackage(clientId, messageId, transType, date, md5Hex, GzipCompressUtils.compress(json));

            String content = create.toJson(messagePackage);
            Log.e("t", "==" + content);
            invokePost(url, content, new JsonCallback<TransMessage>() {
                @Override
                public void onResponse(TransMessage response, int id) {
                    String mMessage = response.getMessage();
                    if (response != null) {
                        try {
                            mMessage = GzipCompressUtils.unCompress(mMessage);
                            Log.e("t", mMessage);
                            response.setMessage(mMessage);

                            //Gson create = gsonBuilder.create();
                            //Object o = create.fromJson(mMessage, transType.getResponseType());
                            callback.onResponse(response, id);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }

                @Override
                public void onFail(Call call, Exception e, int id) {
                    callback.onError(call, e, id);
                }

                @Override
                public void onError(Call call, Exception e, int id) {
                    super.onError(call, e, id);
                    callback.onError(call, e, id);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }


    }


    private static void invokeGet(String url, HashMap params, Callback callback) {
        OkHttpUtils.get().url(url)
                .params(params == null ? new HashMap<String, String>() : params)
                .build()
                .execute(callback);
    }

    private static void invokePost(String url, String content, Callback callback) {
        OkHttpUtils.postString().url(url).content(content)
                .addHeader("Accept", "application/xml,application/json")
                .addHeader("Accept-Charset", "UTF-8")
                .mediaType(MediaType.parse("application/json"))
                .addHeader("ContentType", "application/json")
                .build()
                .execute(callback);
    }

    private static String formatDate(String pattern, Date date) {
        return new SimpleDateFormat(pattern, Locale.getDefault()).format(date);
    }

    private static final String CLIENT_REQUEST_DATETIME_PATTERN = "yyyyMMddHHmmss";

    @SuppressLint("SimpleDateFormat")
    private static GsonBuilder createGson() {
        final SimpleDateFormat sdf = new SimpleDateFormat(CLIENT_REQUEST_DATETIME_PATTERN);
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
            @Override
            public Date deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
                    throws JsonParseException {
                try {
                    return sdf.parse(json.getAsString());
                } catch (ParseException e) {
                    throw new RuntimeException("日期{" + json.getAsString() + "}格式不对, Pattern应该为: "
                            + CLIENT_REQUEST_DATETIME_PATTERN, e);
                } catch (Exception e) {
                    throw new RuntimeException("日期转换错误{" + json.toString() + "}", e);
                }
            }
        });
        gsonBuilder.registerTypeAdapter(Date.class, new JsonSerializer<Date>() {
            @Override
            public JsonElement serialize(Date arg0, Type arg1, JsonSerializationContext arg2) {
                return new JsonPrimitive(sdf.format(arg0));
            }
        });
        return gsonBuilder;
    }


}
